//
//  SimParams.h
//  WORM_ALPT
//
//  Created by Snir Gazit on 8/9/11.
//  Copyright 2011 __MyCompanyName_. All rights reserved.
//

#ifndef WORM_AL_PT_SimParamsh
#define WORM_AL_PT_SimParamsh

#include "HelpLibs/def.h"
#include "ParticlePos.h"
//#include "xml_rw.h"
#include "HelpLibs/hdf5RW.h"
#include "HelpLibs/ArrayMultiD.h"
struct measurements {
	bool SF;
	bool Density;
	bool Rho;
	bool Winding;
	bool JqJq;
	bool Energy;
	bool Angle;
	bool DensityPhonon;
	bool DensitySym;
};
struct potentials {
	bool Free;
	bool Harmonic;
	bool Log;
	double Omega;
};

class PTParams {
public:
	vector<double> RSS;
	vector<string> outDirs, initDirs;
	string outPathPT;
	int numOfConf;
	string PTOutFile;
	int numAdjustLambda;
	int numAdjustRuns;
	int numAdjustPar;
	int maxDelta;
	int numSplit;
	int numPar;
	double runTime;
	// PT run number for split runs
	int runNum;
	string initPath;
	string initType;
	int coreNum;
	int numRunsPrint;
};

template<int size>
class Histogram {
private:
	size_t numOfSamp_;
	array<std::size_t, size> samps_;
public:
	void init() {
		numOfSamp_ = 0;
		samps_.fill(0);
	}
	;
	void update(int pos) {
		samps_[pos] += 1;
		numOfSamp_++;
	}
	double getPrecentage(int pos) {
		return double(samps_[pos]) / double(numOfSamp_);
	}
};

struct statistics {
	// Prob Blotz
	boost::array<acc, NUM_OF_MOVES> Boltzman;
	// Prob Rho
	acc Rho;
	// Prob Swap
	acc Swap;
	// Prob Swap Same
	acc SwapSame;
	// try to swap on the same world line
	unsigned long int swapSame;
	Histogram<4> moves;
	void init() {
		Boltzman.fill(acc());
		Rho = acc();
		Swap = acc();
		SwapSame = acc();
		moves.init();
	}
	void dumpToFile(string fileName) {
		ofstream fs;
		try {
			fs.open(fileName);
		} catch (exception &e) {
			cout << e.what();
			exit(1);
		}
		YAML::Emitter out;
		out << YAML::BeginMap;
		out << YAML::Key << "moves";
		out << YAML::BeginMap;
		for (int i = 0; i < 4; i++) {
			string move_type;
			switch (i) {
			case 0:
				move_type = "WIGGLE";
				break;
			case 1:
				move_type = "CLOSE";
				break;
			case 2:
				move_type = "SWAP";
				break;
			case 3:
				move_type = "OPEN";
				break;
			}
			out << YAML::Key << move_type;
			root_node["MOVE_TYPE"];
			addData(root_node, "MOVE_TYPE", moves.getPrecentage(i));
			addData(root_node, "BLZ", ba::mean(Boltzman[i]));
		}
		pugi::xml_node root_node;
		root_node = stat_node.append_child("RHO");
		addData(root_node, "RHO", ba::mean(Rho));
		root_node = stat_node.append_child("RHO");
		addData(root_node, "SWAP", ba::mean(Swap));
		root_node = stat_node.append_child("RHO");
		addData(root_node, "SWAP_SAME", ba::mean(SwapSame));
		doc.save_file(fileName.c_str());
	}
};
#endif
